//*********************************************************************
//		Copyright (c) 2003 - 2008 Microsoft Corporation.
//      This code is provided under Microsoft Public License, which can be found at
//      http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx 
//
// @File: Collector_EventLog_support.cs
//
// Purpose: supporting classes for EventLog Collector
//
//
//
// Notes: 
//
//
//	
// History: 
//     @Version: V2.1
//
//     07/14/08 PGV 2.1.001.0 Starting V2.1 (based on 2.0.030.0 code)
//
//
// @EndHeader@
//*********************************************************************

using System;
using System.Collections;
using System.Diagnostics;

using H2V2;

namespace H2V2.Collector
{
	#region Log collector supporting structures & classes
	public class SystemLogEvent 
	{
		public int EventID;
		public DateTime TimeGenerated;
		public DateTime TimeReferenced;
		public string Ver;
		public string Build;
		public string Level;

		public string version { get { return Ver+" "+Build+" "+Level; } }
	
		public SystemLogEvent (EventLogEntry a_entry)
		{
			EventID = a_entry.EventID;
			TimeGenerated = a_entry.TimeGenerated;
			TimeReferenced = CollectorBase.MIN_DATE; 

			switch (EventID)
			{
				case 6009:
					TimeReferenced = CollectorBase.MIN_DATE;
					Ver = a_entry.ReplacementStrings[0];
					Build = a_entry.ReplacementStrings[1];
					Level = a_entry.ReplacementStrings[2];
					break;
				case 6008:
					string time = a_entry.ReplacementStrings[1]+" "+a_entry.ReplacementStrings[0];
					TimeReferenced = DateTime.Parse (time);
					break;
			}
		}
	}

	public class SqlServerEvent 
	{
		public short inst_id;
		public int EventID;
		public int SubEventID;
		public DateTime TimeGenerated;
		public string pid;
		public DateTime TimeReferenced;
		public H2ProductLevel level;

		public SqlServerEvent () {}

		public SqlServerEvent (short a_inst_id, EventLogEntry a_entry, int a_sub)
			// Sql2000 events
		{	
			int i,
				len;

			level = H2ProductLevel.UNKNOWN;

			inst_id = a_inst_id;
			EventID = a_entry.EventID;
			TimeGenerated = a_entry.TimeGenerated;
			SubEventID = a_sub;
			TimeReferenced = CollectorBase.MIN_DATE;
			pid = null;

			switch (a_entry.EventID)
			{
				case 17176:
				case 17177:
					pid = a_entry.ReplacementStrings[0];
					TimeReferenced = Convert.ToDateTime(a_entry.ReplacementStrings[1]);
					break;
				case 17052:
					pid = a_entry.ReplacementStrings[0];
					break;
				case 17055:
				switch (a_sub)
				{
					case 17104:
						pid = CollectorEventLog.ParsePidFromEvent17104 (a_entry.ReplacementStrings[1]);
						TimeReferenced = TimeGenerated;
						break;
					case 17052:
						if (a_entry.ReplacementStrings[1].StartsWith("Microsoft SQL Server"))
						{
							pid = a_entry.ReplacementStrings[1].Substring (29, 8);

							Version v = new Version (pid);
							if (v.Major < 7 || (v.Major == 8 && v.Build < 760))
							{
								level = H2ProductLevel.PreSql2000SP3;
							}
							else
							{
								level = H2ProductLevel.Sql2000SP3;
							}
 						}
						break;
					case 19030:
					case 19031:
						//SQL Trace started.|Trace ID = '1'|Login Name = '...'
						i = 32;
						len = 0;
						while (Char.IsDigit((a_entry.ReplacementStrings[1])[i++])) len++;  
						pid = a_entry.ReplacementStrings[1].Substring (32, len);
						break;
					case 19032:
						//SQL Trace stopped due to server shutdown.|Trace ID = '1'
						i = 55;
						len = 0;
						while (Char.IsDigit((a_entry.ReplacementStrings[1])[i++])) len++;  
						pid = a_entry.ReplacementStrings[1].Substring (55, len);
						break;
					case 17065:
					case 17066:
					case 17067:
					case 17308:
					case 17310:
					case 17311:
						pid = a_entry.ReplacementStrings[1];
						break;
				}
					break;
			}
		}

		public SqlServerEvent (short a_inst_id, EventLogEntry a_entry)
			//	Sql2005 events
		{
			level = H2ProductLevel.Sql2005;

			inst_id = a_inst_id;
			EventID = a_entry.EventID;
			TimeGenerated = a_entry.TimeGenerated;
			SubEventID = 0;
			TimeReferenced = CollectorBase.MIN_DATE;
			pid = null;

			switch (a_entry.EventID)
			{
				case 17176:
				case 17177:
					pid = a_entry.ReplacementStrings[0];
					TimeReferenced = Convert.ToDateTime(a_entry.ReplacementStrings[1]);
					break;
				case 17104:
					pid = a_entry.ReplacementStrings[0];
					TimeReferenced = TimeGenerated;
					break;
				case 17052:
					if (a_entry.ReplacementStrings[0].StartsWith("Microsoft SQL Server"))
					{
						pid = a_entry.ReplacementStrings[0].Substring (29, 8);
					}
					break;
				case 19030:
				case 19031:
				case 19032:
					//SQL Trace started.|Trace ID = '1'|Login Name = '...'
					pid = a_entry.ReplacementStrings[0];
					break;
			}
		}
	}

	public struct BoundaryEvent
	{
		public int index;
		public DateTime TimeGenerated;
	}

	public struct LogHistoryRecord
	{
		public int count;
		public BoundaryEvent start;
		public BoundaryEvent finish;
		public BoundaryEvent cutoff;
		public bool NoHistory;
		public bool IsGap; 
		public int prev_run_id;
	}

	public struct AppLogEvent
	{
		public int EventID;
		public DateTime TimeGenerated;
		public string Source;
		public string info;

		public AppLogEvent (EventLogEntry a_entry, int a_idx)
		{
			EventID = a_entry.EventID;
			TimeGenerated = a_entry.TimeGenerated;
			Source = a_entry.Source;
			info = a_entry.ReplacementStrings[a_idx];
		}

		public AppLogEvent (EventLogEntry a_entry)
		{
			EventID = a_entry.EventID;
			TimeGenerated = a_entry.TimeGenerated;
			Source = a_entry.Source;
			info = "";
			foreach (string s in a_entry.ReplacementStrings)
			{
				info += s + ",";
			}
		}
	}

	public class LogSource 
	{
		public string name;
		public short inst_id;
		public H2ProductLevel level;	// Currently running/installed version
		public H2ProductLevel hlevel;	// Historical level - level of the last added event
		ArrayList m_event_array;
		SortedList m_event_registry;
		public SortedList EventRegistry { get { return m_event_registry; } }

		public LogSource (string a_name, short a_inst_id, H2ProductLevel a_level)
		{
			name = a_name;
			inst_id = a_inst_id;
			level = a_level;
			hlevel = H2ProductLevel.UNKNOWN; 

			m_event_array = new ArrayList (100);
			m_event_registry = new SortedList (64);
		}

		public void addEvent (SqlServerEvent a_event)
		{
			m_event_array.Add (a_event);
		}

		public int Count { get {return m_event_array.Count;} }

		public object this [int idx]
		{
			get {return m_event_array[idx];} 
		}

		public void addRegistryEvent (int a_eventID)
		{
			int idx,
				q;

			if (m_event_registry.ContainsKey (a_eventID))
			{
				idx = m_event_registry.IndexOfKey (a_eventID);
				q = (int)m_event_registry[a_eventID];
				++q;
				m_event_registry.SetByIndex (idx, q);
			}
			else
			{
				m_event_registry.Add (a_eventID, 1);
			}
		}
	}

	public class LogSourceCollection 
	{
		SortedList m_sources;
		public int Count { get { return m_sources.Count; } }

		public LogSourceCollection ()
		{
			m_sources = new SortedList (4);
		}

		public object this [int idx]
		{
			get {return m_sources.GetByIndex (idx);}
		}

		public void Add (LogSource a_source)
		{
			string src = a_source.name.ToUpper ();
			m_sources.Add (a_source.name, a_source);
		}

		public LogSource GetSource (string a_source)
		{
			string src = a_source.ToUpper ();

			try
			{
				return (LogSource)m_sources[a_source];
			}
			catch (InvalidOperationException)
			{
				return null;
			}
		}
	}

	#endregion
}

